package sg.edu.nus.iss.billing.gui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

import java.io.FileInputStream;
import java.util.*;
import java.util.List;

import sg.edu.nus.iss.billing.BillingApplication;
import sg.edu.nus.iss.billing.BillingConstants;
import sg.edu.nus.iss.billing.BillingConstants.SearchTypes;
import sg.edu.nus.iss.billing.BillingConstants.SystemState;
import sg.edu.nus.iss.billing.model.user.User.SystemRole;

/**
 * @author Yeo Hee Ling, Ananda, Saravana
 *
 */
public class BillingWindow extends JFrame implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	
	// Declaration of Global Variables.
	private Properties properties;
	private BillingApplication billingAppl;
	private JPanel bodyPanel;
	private AbstractButton menuNewUser, menuExistingUser, menuNewCustomer, menuExistingCustomer, menuSubscriptions, menuNewComplaints, menuExistingComplaints, menuViewBill, menuGenerateBill, menuLogout;

	
	// Class Constructor.
	public BillingWindow(BillingApplication billingAppl) {
		super("One# Billing Application");
		this.billingAppl = billingAppl;
		
		loadConfiguration();
		
		bodyPanel = initBodyPanel();
		Container container = this.getContentPane();
		container.add(initHeaderPanel(), BorderLayout.NORTH);
		container.add(bodyPanel, BorderLayout.CENTER);
		
		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		addWindowListener(windowListener);
		
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		int x = (screen.width/2) - (StyleConstants.WINDOW_WIDTH/2);
		int y = (screen.height/2) - (StyleConstants.WINDOW_HEIGHT/2);
		this.setMinimumSize(new Dimension(StyleConstants.WINDOW_WIDTH, StyleConstants.WINDOW_HEIGHT));
		this.setBounds(x, y, StyleConstants.WINDOW_WIDTH, StyleConstants.WINDOW_HEIGHT);
		this.setResizable(false);
		this.setVisible(true);
	}
	
	private void loadConfiguration() {
		try {
			properties = new Properties();
			FileInputStream in = new FileInputStream(BillingConstants.PROPERTIES_APPLICATION);
			properties.load(in);
			in.close();
		}
		catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	
	private JPanel initBodyPanel() {
		JLabel msgLabel = new JLabel("<html><div align=\"center\">Welcome to #One Billing System.<br>By<br>Team: SE19(Saturday)</div></html>");
		msgLabel.setFont(new Font("Tahoma", Font.BOLD, 32));
		msgLabel.setHorizontalAlignment(SwingConstants.CENTER);
		
		JPanel framePanel = new StylePanel();
		framePanel.setLayout(new BorderLayout());
		framePanel.add(msgLabel, BorderLayout.CENTER);
		
		return framePanel;
	}
	
	private WindowListener windowListener = new WindowAdapter () {
        public void windowClosing (WindowEvent e) {
        	int res = JOptionPane.showConfirmDialog(null, properties.getProperty("info.message.applicationExit"), properties.getProperty("title.application.exit"), JOptionPane.OK_CANCEL_OPTION);
        	if(res == 0)
        		billingAppl.shutdown();
        }
    };
 
    private JPanel initHeaderPanel() {
		JPanel menuPanel = new JPanel();
		menuPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		menuPanel.add(getToolBar());
		
		JPanel headerPanel = new JPanel();
		headerPanel.setLayout(new BorderLayout());
		headerPanel.add(menuPanel, BorderLayout.CENTER);
		
		return headerPanel;
	}
	
	private JToolBar getToolBar() {
		JToolBar toolBar = new JToolBar();
		List<AbstractButton> subItems = new ArrayList<AbstractButton>();
		
		if(BillingApplication.getUserSession().getSystemRole() == SystemRole.ADMIN) {
			subItems.add(menuNewUser = new JMenuItem(properties.getProperty("label.mainmenu.newUser")));
			subItems.add(menuExistingUser = new JMenuItem(properties.getProperty("label.mainmenu.existingUser")));
			toolBar.add(GetToolbarButton(properties.getProperty("label.mainmenu.admin"), subItems));
		}
		
		subItems = new ArrayList<AbstractButton>();
		if(BillingApplication.getUserSession().getSystemRole() == SystemRole.ADMIN) {
			subItems.add(menuNewCustomer = new JMenuItem(properties.getProperty("label.mainmenu.newCustomerAcct")));
		}
		subItems.add(menuExistingCustomer = new JMenuItem(properties.getProperty("label.mainmenu.existingCustomerAcct")));
        toolBar.add(GetToolbarButton(properties.getProperty("label.mainmenu.customerAcct"), subItems));
        
        menuSubscriptions = GetToolbarButton(properties.getProperty("label.mainmenu.subscriptions"));
        toolBar.add(menuSubscriptions);
        
        subItems = new ArrayList<AbstractButton>();
		subItems.add(menuNewComplaints = new JMenuItem(properties.getProperty("label.mainmenu.newComplaints")));
        subItems.add(menuExistingComplaints = new JMenuItem(properties.getProperty("label.mainmenu.existingComplaints")));
        toolBar.add(GetToolbarButton(properties.getProperty("label.mainmenu.complaints"), subItems));
        
        subItems = new ArrayList<AbstractButton>();
		subItems.add(menuViewBill = new JMenuItem(properties.getProperty("label.mainmenu.viewBill")));
		if(BillingApplication.getUserSession().getSystemRole() == SystemRole.ADMIN) {
			subItems.add(menuGenerateBill = new JMenuItem(properties.getProperty("label.mainmenu.generateBills")));
		}
        toolBar.add(GetToolbarButton(properties.getProperty("label.mainmenu.bill"), subItems));
        
        menuLogout = GetToolbarButton(properties.getProperty("label.mainmenu.logout"));
        toolBar.add(menuLogout);
        
		toolBar.setLayout(new GridLayout(1,5));
        toolBar.setFloatable(false);
        toolBar.setPreferredSize(new Dimension(StyleConstants.WINDOW_WIDTH, 50));
        
        return toolBar;
	}
	
    private AbstractButton GetToolbarButton(String name, List<AbstractButton> subItems) {
        final JToggleButton button = new JToggleButton(name);
        final List<AbstractButton> items = new ArrayList<AbstractButton>();
        
        for(AbstractButton menuItem : subItems) {
            items.add(menuItem);
            menuItem.setFont(StyleConstants.MENU_FONT);
            menuItem.addActionListener(this);
        }
        
        button.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    createAndShowMenu((JComponent) e.getSource(), button, items);
                }
            }
        });
        
        button.setFocusable(false);
        button.setFont(StyleConstants.MENU_FONT);
        return button;
    }
    
    private AbstractButton GetToolbarButton(String name) {
        final JButton button = new JButton(name);
        button.setFont(StyleConstants.MENU_FONT);
        button.setHorizontalTextPosition(SwingConstants.LEADING);
        button.setFocusable(false);
        button.addActionListener(this);
        return button;
    }

    private void createAndShowMenu(JComponent component, final JToggleButton button, List<AbstractButton> items) {
        JPopupMenu menu = new JPopupMenu();
        menu.setPreferredSize(new Dimension(StyleConstants.WINDOW_WIDTH/5, 50*items.size()));
        menu.setLayout(new GridLayout(items.size(), 1));
        for(AbstractButton item : items) {
        	menu.add(item);
        }

        menu.addPopupMenuListener(new PopupMenuListener() {
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            	button.setSelected(false);
            }

            public void popupMenuCanceled(PopupMenuEvent e) {
            	button.setSelected(false);
            }
        });

        menu.show(component, 0, component.getHeight());
    }

    public void switchPage(JComponent component){
    	bodyPanel.removeAll();
		bodyPanel.add(component, BorderLayout.NORTH);
		bodyPanel.getRootPane().revalidate();
		this.getContentPane().repaint();
    }
    
	public void actionPerformed(ActionEvent e) {
		
		if(e.getSource() == menuNewUser) {
			switchPage(new UserPanel(billingAppl, SystemState.SYSTEM_USER_CREATE, null, null));
		}
		else if(e.getSource() == menuExistingUser) {
			switchPage(new SearchUserPanel(billingAppl));
		}
		else if(e.getSource() == menuNewCustomer) {
			switchPage(new CustomerPanel(billingAppl, SystemState.CUSTOMER_REGISTER, null, null));
		}
		else if(e.getSource() == menuExistingCustomer) {
			switchPage(new SearchCustomerPanel(billingAppl, SearchTypes.EXISTING_ACC));
		}
		else if(e.getSource() == menuSubscriptions) {
			switchPage(new SearchCustomerPanel(billingAppl, SearchTypes.SUBSCRIPTIONS));
		}
		else if(e.getSource() == menuNewComplaints) {
			switchPage(new SearchCustomerPanel(billingAppl, SearchTypes.COMPLAINTS));
		}
		else if(e.getSource() == menuExistingComplaints) {
			switchPage(new SearchComplaintPanel(billingAppl));
		}
		else if(e.getSource() == menuViewBill) {
			switchPage(new SearchCustomerPanel(billingAppl, SearchTypes.VIEW_BILL));
		}
		else if(e.getSource() == menuGenerateBill) {
			switchPage(new BillPanel(billingAppl, SystemState.BILL_GENERATE_MTHLY, null, null, null));
		}
		else if(e.getSource() == menuLogout) {
			billingAppl.displayLoginPage();
		}
	}
	
}